package com.ceo.auth;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.ceo.common.utils.YamlUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * @author uto_dev_008
 * @desc
 * @since 2021/11/24 16:21
 * Copyright (c)  All rights reserved
 */
public class CodeGenerator {

    /**
     * 读取控制台内容
     */
    public static String readLine(String tip) {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        try {
            str = bf.readLine();
            if (str.length() == 0 || str.trim().length() == 0) { // 如果输入的字符串为空，copy则说知明只输入了一个回车
                return "";
            } else {
                return str.trim();
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new MybatisPlusException("please input:" + tip + "!");
        }
    }

    private static YamlUtil yaml;

    public static void main(String[] args) {
        // default package
        String packageName = CodeGenerator.class.getPackage().getName();
        ; // 生成的包名
        String author = "uto_dev_";
        boolean serviceNameStartWithI = false; // user -> UserService, 设置成true: user -> IUserService

        // 交互输入author
        StringBuilder help = new StringBuilder();
        help.append("default author is uto_dev_(input author name):");
        System.out.println(help);
        String tmp = readLine("author name");
        if (StringUtils.isNotBlank(tmp)) {
            author = tmp;
        }

        // 交互输入包名
        help.delete(0, help.length());
        help.append("default package is " + packageName + " enter continue or input your package:");
        System.out.println(help);
        tmp = readLine("package name");
        packageName = StringUtils.isNotBlank(tmp) ? tmp : packageName;

        // 路径相关默认设置
        StringBuilder dir = new StringBuilder();
        String srcDir = "/src/main/java";
        // 获取当前路径
        // dir.append(System.getProperty("user.dir")).append("/");
        // 默认模块路径
        String absPath = CodeGenerator.class.getClass().getResource("/").getPath();
        String[] paths = absPath.split("/target", 0);
        // String defaultDir = paths[paths.length-1].split("/target",0)[0];
        dir.append(paths[0]);

        help.delete(0, help.length());
        help.append(
                "default directory is "
                        + dir
                        + " enter continue or input your directory from '{projectName/'):");
        System.out.println(help);
        tmp = readLine("your directory");

        if (StringUtils.isNotBlank(tmp)) {
            dir.append(tmp).append(srcDir);
        } else {
            dir.append(srcDir);
        }

        // 读取yml文件
        help.delete(0, help.length());
        help.append("please enter your profiles active(default dev):");
        System.out.println(help);
        String active = "dev";
        active = readLine("profiles active");
        if (StrUtil.isEmpty(active)) {
            active = "dev";
        }
        String ymlPath = dir.toString().split("java")[0] + "resources/application-" + active + ".yml";
        yaml = new YamlUtil(ymlPath);

        DbType dbType = DbType.ORACLE;
        if (active.contains("dev") || active.contains("intg") || active.contains("prod")) {
            dbType = DbType.MYSQL;
        } else if (active.contains("orcale")) {
            dbType = DbType.ORACLE;
        } else if (active.contains("sqlserver")) {
            dbType = DbType.SQL_SERVER;
        }
        // 交互输入数据库名
        String dbName = "";
        help.delete(0, help.length());
        LinkedHashMap<String,Object> dbMap = new LinkedHashMap<>();
        dbMap.put("master","");
        dbMap = yaml.getValueByKey("spring.datasource.dynamic.datasource", dbMap);
        help.append("input your datasource name:(" + dbMap.keySet() + ")");
        while (StringUtils.isBlank(dbName)) {
            System.out.println(help);
            dbName = readLine("datasource name");
        }
        // 交互输入表名
        String tableName = "";
        help.delete(0, help.length());
        help.append("input your table name:");
        while (StringUtils.isBlank(tableName)) {
            System.out.println(help);
            tableName = readLine("table name");
        }

        //  tablenames  是需要生成的数据表名称
        generateByTables(serviceNameStartWithI, packageName, dir.toString(), author, dbType,dbName, tableName);
    }

    private static void generateByTables(
            boolean serviceNameStartWithI,
            String packageName,
            String dir,
            String author,
            DbType dbType,
            String dbName,
            String... tableNames) {

        String pkgDir = packageName.replace('.', '/');
        pkgDir = "/" + pkgDir;
        // 设置不同类文件生成的路径
        HashMap<String, String> pathInfo = new HashMap<>();
        pathInfo.put(ConstVal.ENTITY_PATH, dir + pkgDir + "/entity/");
        pathInfo.put(ConstVal.MAPPER_PATH, dir + pkgDir + "/mapper/");
        pathInfo.put(ConstVal.XML_PATH, dir.split("java")[0] + "resources/mapper/");
        pathInfo.put(ConstVal.CONTROLLER_PATH, dir + pkgDir + "/controller/");
        pathInfo.put(ConstVal.SERVICE_PATH, dir + pkgDir + "/service/");
        pathInfo.put(ConstVal.SERVICE_IMPL_PATH, dir + pkgDir + "/service/impl/");

        GlobalConfig config = new GlobalConfig();

        String defaultVal = "com.microsoft.sqlserver.jdbc.SQLServerDriver";

        String driverStr = yaml.getValueByKey("spring.datasource.dynamic.datasource."+dbName+".driver-class-name",defaultVal);
        String dbUrl = yaml.getValueByKey("spring.datasource.dynamic.datasource."+dbName+".url",defaultVal);
        String dbUsername = yaml.getValueByKey("spring.datasource.dynamic.datasource."+dbName+".username",defaultVal);
        String dbpwd = yaml.getValueByKey("spring.datasource.dynamic.datasource."+dbName+".password",defaultVal);

        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig
                .setDbType(dbType)
                .setUrl(dbUrl)
                .setUsername(dbUsername)
                .setPassword(dbpwd)
                .setDriverName(driverStr);
        // 策略配置
        StrategyConfig strategyConfig = new StrategyConfig();

        strategyConfig.setInclude(tableNames);
        // strategyConfig.setExclude(null);
        strategyConfig
                .setCapitalMode(false) // 全局大写命名
                .setEntityLombokModel(false)
                // .setTablePrefix("tb_") // 去除表前缀
                .setColumnNaming(NamingStrategy.underline_to_camel)
                .setRestControllerStyle(true)
                .setNaming(NamingStrategy.underline_to_camel) // // underline_to_camel数据库表映射到实体的命名策略

                // 设置公共父类路径
                .setSuperMapperClass("com.baomidou.mybatisplus.core.mapper.BaseMapper")
                .setSuperServiceClass("com.baomidou.mybatisplus.extension.service.IService")
                .setSuperEntityClass(com.ceo.common.entity.BaseEntity.class)
                .setSuperControllerClass(com.ceo.common.controller.BaseController.class)
                .setSuperServiceImplClass("com.baomidou.mybatisplus.extension.service.impl.ServiceImpl");

        // 全局配置
        config
                .setActiveRecord(true) // 是否支持AR模式
                .setAuthor(author) // 设置作者
                .setOutputDir(dir) // 设置生成的目标路径（绝对路径）
                .setIdType(IdType.INPUT) // 主键策略 代码生成UUID
                .setBaseColumnList(true) // 设置sql片段
                .setBaseResultMap(true) // resultMap
                .setEnableCache(false) // 不开缓存
                .setMapperName("%sMapper")
                .setXmlName("%sMapper")
                .setOpen(false) // 生成之后 默认打开文件夹
                .setSwagger2(true)
                .setFileOverride(false); // 每一次生成需要覆盖
        if (!serviceNameStartWithI) {
            config.setServiceName("%sService");
        }
        new AutoGenerator()
                .setGlobalConfig(config)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(
                        new PackageConfig()
                                .setParent(packageName)
                                .setController("controller")
                                .setEntity("entity")
                                .setMapper("mapper")
                                .setPathInfo(pathInfo))
                .execute();
    }

}
